﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using SharedGenomics.Workbench.Models;

namespace SharedGenomics.Workbench.Tests.Models
{
    [TestClass]
    public class DataGridSourceTests
    {
        [TestMethod]
        public void ShouldLoadItems()
        {
            DataGridSource<string> s = new DataGridSource<string>();
            s.LoadItems(new[] { "a", "b", "c" });
            Assert.AreEqual(3, s.Count);
        }

        [TestMethod]
        public void LoadShouldRaiseListChangedEvent()
        {
            DataGridSource<string> dgs = new DataGridSource<string>();
            this.AssertListChangedRaised(dgs, s => s.LoadItems(new[] { "a", "b", "c" }));
        }

        [TestMethod]
        public void LoadShouldRaiseItemsChangedEvent()
        {
            bool eventRaised = false;
            DataGridSource<string> dgs = new DataGridSource<string>();
            dgs.ItemsChanged += (o, e) => { eventRaised = true; };

            dgs.LoadItems(new[] { "a", "b", "c" });
            Assert.IsTrue(eventRaised);
        }

        [TestMethod]
        public void ShouldFilter()
        {
            DataGridSource<string> s = new DataGridSource<string>();
            s.LoadItems(new[] { "a", "b", "c" });

            s.Filter = i => i == "a";
            Assert.AreEqual(1, s.Count);
        }

        [TestMethod]
        public void ShouldRemoveFilter()
        {
            DataGridSource<string> s = new DataGridSource<string>();
            s.Filter = i => i == "a";

            s.LoadItems(new[] { "a", "b", "c" });
            s.Filter = null;
            Assert.AreEqual(3, s.Count);
        }

        [TestMethod]
        public void FilterShouldRaiseListChangedEvent()
        {
            DataGridSource<string> dgs = new DataGridSource<string>();
            dgs.LoadItems(new[] { "a", "b", "c" });

            this.AssertListChangedRaised(dgs, s => s.Filter = i => i == "a");
        }

        [TestMethod]
        public void RemoveFilterShouldRaiseListChangedEvent()
        {
            DataGridSource<string> dgs = new DataGridSource<string>();
            dgs.Filter = i => i == "a";
            dgs.LoadItems(new[] { "a", "b", "c" });

            this.AssertListChangedRaised(dgs, s => s.Filter = null);
        }

        [TestMethod]
        public void ShouldApplyFilterOnLoad()
        {
            DataGridSource<string> s = new DataGridSource<string>();
            s.Filter = i => i.Length > 1;
            s.LoadItems(new[] { "a", "ab", "abc" });
            Assert.AreEqual(2, s.Count);
        }

        [TestMethod]
        public void ShouldClearList()
        {
            DataGridSource<string> s = new DataGridSource<string>();
            s.LoadItems(new[] { "a" });
            s.Clear();
            Assert.AreEqual(0, s.Count);
        }

        [TestMethod]
        public void ClearShouldRaiseListChangedEvent()
        {
            DataGridSource<string> dgs = new DataGridSource<string>();
            dgs.LoadItems(new[] { "a" });
            this.AssertListChangedRaised(dgs, s => s.Clear());
        }

        [TestMethod]
        public void ClearShouldRaiseItemsChangedEvent()
        {
            bool eventRaised = false;
            DataGridSource<string> dgs = new DataGridSource<string>();
            dgs.LoadItems(new[] { "a", "b", "c" });

            dgs.ItemsChanged += (o, e) => { eventRaised = true; };
            dgs.Clear();
            Assert.IsTrue(eventRaised);
        }

        [TestMethod]
        public void ShouldSortAscending()
        {
            DataGridSource<string> dgs = new DataGridSource<string>();
            dgs.LoadItems(new[] { "abc", "a", "ab" });
            var lengthProp = TypeDescriptor.GetProperties(typeof(string))["Length"];
            ((IBindingList)dgs).ApplySort(lengthProp, ListSortDirection.Ascending);

            CollectionAssert.AreEqual(new[] { "a", "ab", "abc" }, dgs);
        }

        private void AssertListChangedRaised<T>(DataGridSource<T> gridSource, Action<DataGridSource<T>> act)
        {
            bool eventRaised = false;
            gridSource.ListChanged += (o, e) => { eventRaised = true; };
            act(gridSource);
            Assert.IsTrue(eventRaised);
        }
    }
}
